package com.omega_r.libs.omegarecyclerview.viewpager;

import ohos.agp.components.*;
import ohos.app.Context;
import ohos.eventhandler.EventRunner;
import ohos.global.resource.NotExistException;
import ohos.global.resource.WrongTypeException;
import ohos.multimodalinput.event.MmiPoint;
import ohos.multimodalinput.event.TouchEvent;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;


public class OmegaPagerRecyclerView extends PageSlider implements PageSlider.PageChangedListener {
    private final HashMap<Integer, Component> mapItem = new HashMap<>();
    // 是否左滑
    private boolean isLeftMove = false;
    private List<Component> mComponents;
    private PageTransformer mPageTransformer;

    private int delayTime = 2000;
    private boolean isAutoPlay = true;
    private boolean isLoop = true;
    private int count = 0;
    private List mDatas;
    private BannerViewHolder creator;
    private List<Component> imageViews;
    private int currentItem = 0;
    private BannerPagerAdapter adapter;
    private OnBannerClickListener listener;
    private EventRunner runner = EventRunner.current();
    private WeakHandler handler = new WeakHandler(runner);

    /**
     * 此类为了适配PageSlide滑动监听参数问题
     *
     * @param context
     */
    public OmegaPagerRecyclerView(Context context) {
        this(context, null);
    }

    /**
     * 此类为了适配PageSlide滑动监听参数问题
     *
     * @param context
     * @param attrSet
     */
    public OmegaPagerRecyclerView(Context context, AttrSet attrSet) {
        this(context, attrSet, null);
    }

    /**
     * 此类为了适配PageSlide滑动监听参数问题
     *
     * @param context
     * @param attrSet
     * @param styleName
     */
    public OmegaPagerRecyclerView(Context context, AttrSet attrSet, String styleName) {
        super(context, attrSet, styleName);
        addPageChangedListener(this);
        mDatas = new ArrayList<>();
        imageViews = new ArrayList<>();
        mComponents = new ArrayList<>();
    }

    @Override
    public void onPageSliding(int position, float positionOffset, int positionOffsetPixels) {
        if (mPageTransformer != null) {
            onPageScrolled(position, positionOffset, positionOffsetPixels);
        }
    }

    @Override
    public void onPageSlideStateChanged(int state) {
    }

    @Override
    public void onPageChosen(int position) {

    }

    /**
     * 设置PageSlide所有子组件
     *
     * @param components 子组件集合
     */
    public void setPages(List<Component> components) {
        this.mComponents = components;
    }

    /**
     * 设置动画接口
     *
     * @param pageTransformer 动画接口实现类
     */
    public void setPageTransformer(PageTransformer pageTransformer) {
        this.mPageTransformer = pageTransformer;
    }

    private void onPageScrolled(int position, float itemPosOffset,  int itemPosOffsetPixels ) {
        if (mPageTransformer != null) {
            onPageTransformer(position, itemPosOffset, itemPosOffsetPixels);
        }
    }

    private void onPageTransformer(int position, float positionOffset, int offsetPixels) {
        if (offsetPixels > getEstimatedWidth()) {
            positionOffset = (float) (offsetPixels - getEstimatedWidth()) / getEstimatedWidth();

        }else if (isLeftMove && offsetPixels > 0) {
                offsetPixels = offsetPixels-getEstimatedWidth() ;
            positionOffset = 1f - positionOffset;
        }
        System.out.printf("======itemPos=%s，itemPosOffset=%s，itemPosOffsetPixels=%s%n", position, positionOffset, offsetPixels);

        if (offsetPixels > 0) {
            scrollLeft(position, positionOffset);
        } else {
            scrollRight(position, positionOffset);
        }
    }


    private void scrollRight(int position, float positionOffset) {
        // 从左往右滑动
        if (position - 1 >= 0) {
            Component in = mapItem.get(position - 1);
            mPageTransformer.transformPage(in, -1 + positionOffset);
        }
        Component out = mapItem.get(position);
        mPageTransformer.transformPage(out, positionOffset);


    }

    private void scrollLeft(int position, float positionOffset) {
         if (position==mapItem.size()-1) {
             Component in = mapItem.get(0);
             mPageTransformer.transformPage(in, 1 - positionOffset);
         }else {
             Component in = mapItem.get(position+1);
             mPageTransformer.transformPage(in, 1 - positionOffset);
         }
        Component out = mapItem.get(position);
        mPageTransformer.transformPage(out, 0 - positionOffset);
    }


    /**
     * 设置页面切换动画
     *
     * @param transformer 动画
     * @return Banner
     */
    public OmegaPagerRecyclerView setBannerAnimation(Class<? extends OmegaPagerRecyclerView.PageTransformer> transformer) {
        try {
            setPageTransformer(transformer.newInstance());
        } catch (Exception e) {
            e.printStackTrace();
        }
        return this;
    }

    /**
     * PageSlide的动画接口
     *
     * @since 2021-04-12
     */
    public interface PageTransformer {
        /**
         * 动画接口
         *
         * @param page
         * @param position
         */
        void transformPage(Component page, float position);
    }

    /**
     * 开始轮播
     *
     * @return Banner
     */
    public OmegaPagerRecyclerView start() {
        if (count > 0) {
            setData();
        }
        return this;
    }

    /**
     * 设置自动播放
     *
     * @param isAutoPlay isAutoPlay
     * @return Banner
     */
    public OmegaPagerRecyclerView setAutoPlay(boolean isAutoPlay) {
        this.isAutoPlay = isAutoPlay;
        return this;
    }

    /**
     * 设置是否循环
     *
     * @param isLoop isLoop
     * @return Banner
     */
    public OmegaPagerRecyclerView setLoop(boolean isLoop) {
        this.isLoop = isLoop;
        setCircularModeEnabled(isLoop);
        return this;
    }

    /**
     * 设置轮播图
     *
     * @param cpt
     * @return List<Component>
     * @throws NotExistException
     * @throws WrongTypeException
     * @throws IOException
     */
    private List<Component> setComponentList(List<Component> cpt) throws NotExistException, WrongTypeException, IOException {
        imageViews.addAll(cpt);
        return imageViews;
    }

    /**
     * 设置轮播图页面
     *
     * @param datas   datas
     * @param creator BannerViewHolder
     * @return Banner
     */
    public OmegaPagerRecyclerView setPages(List<?> datas, BannerViewHolder creator) {
        this.mDatas.clear();
        this.imageViews.clear();
        this.mDatas.addAll(datas);
        this.creator = creator;
        this.count = datas.size();
        return this;
    }

    /**
     * 绑定数据源
     */
    private void setData() {
        setPages(imageViews);
        if (adapter == null) {
            adapter = new BannerPagerAdapter();
            setCircularModeEnabled(isLoop);
            setProvider(adapter);
        } else {
            adapter.notifyDataChanged();
        }
        this.setTouchEventListener(new TouchEventListener() {
            float downX;
            @Override
            public boolean onTouchEvent(Component component, TouchEvent touchEvent) {
                MmiPoint pointerPosition = touchEvent.getPointerPosition(touchEvent.getIndex());
                switch (touchEvent.getAction()) {
                    case TouchEvent.PRIMARY_POINT_UP:
                    case TouchEvent.CANCEL:
                    case TouchEvent.TOUCH_PANEL:
                        startAutoPlay();
                        break;
                    case TouchEvent.PRIMARY_POINT_DOWN:
                        downX = pointerPosition.getX();
                        stopAutoPlay();
                        break;
                    case TouchEvent.POINT_MOVE:
                        isLeftMove = pointerPosition.getX() - downX > 0;
                        break;
                    default:
                        break;
                }
                return true;
            }
        });
        startAutoPlay();
    }

    /**
     * 开始轮播
     */
    public void startAutoPlay() {
        handler.removeCallbacks(task);
        handler.postDelayed(task, delayTime);
    }

    /**
     * 停止轮播
     */
    public void stopAutoPlay() {
        handler.removeCallbacks(task);
    }

    /**
     * 轮播任务线程
     */
    private final Runnable task = new Runnable() {
        @Override
        public void run() {
            if (count > 1 && isAutoPlay) {
                currentItem++;
                if (currentItem >= count) {
                    currentItem = 0;
                }
                setCurrentPage(currentItem);
                handler.postDelayed(task, delayTime);
            }
        }
    };

    public class BannerPagerAdapter extends PageSliderProvider {

        @Override
        public int getCount() {
            return mDatas.size();
        }

        @Override
        public Object createPageInContainer(ComponentContainer container, int position) {
            Component component = null;
            try {
                component = creator.createView(container.getContext(), position, mDatas.get(position));
            } catch (NotExistException e) {
                e.printStackTrace();
            } catch (WrongTypeException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
            container.addComponent(component);
//            mComponents.add(component);
            mapItem.put(position,component);
            if (listener != null) {
                int finalPosition = position;
                component.setClickedListener(new Component.ClickedListener() {
                    @Override
                    public void onClick(Component component) {
                        listener.onBannerClick(mDatas, finalPosition);
                    }
                });
            }
            return component;
        }

        @Override
        public void destroyPageFromContainer(ComponentContainer container, int i, Object object) {
            container.removeComponent((Component) object);
        }

        @Override
        public boolean isPageMatchToObject(Component component, Object o) {
            return component == o;
        }
    }

    /**
     * 设置点击监听器
     *
     * @param listener
     * @return Banner
     */
    public OmegaPagerRecyclerView setOnBannerClickListener(OnBannerClickListener listener) {
        this.listener = listener;
        return this;
    }
}
